home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / cc03.arc / LUCIFER.C < prev    next >
Text File  |  1986-03-14  |  13KB  |  451 lines

  1. /***************************** lucifer *************************
  2.  * LUCIFER: encrypt/decrypt bytes using IBM's LUCIFER algorithm.
  3.  * Programmed by R.W.Outerbridge
  4.  *
  5.  * Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>
  6.  *          EN/DE      MODES       KEYS
  7.  *
  8.  *    + :    ENcrypt (default if MODE specified)
  9.  *    - :    DEcrypt (presumes encrypted input)
  10.  *
  11.  *    Modes of Operation (choose ONE):
  12.  *
  13.  *    ecb : (default) Electronic Code Book.  Only uses one key.
  14.  *        If simply "+" or "-" is specified, ecb is used.
  15.  *    cbc : Cipher Block Chaining.  Uses two keys.
  16.  *    cks : ChecKSum.  Generates a 128-bit checksum using two keys.
  17.  *
  18.  *    Both keys may be up to 16 characters long.  NON-ASCII MACHINES
  19.  *    MAY GET DIFFERENT RESULTS.  Any character may be used in keys,
  20.  *    but the one letter key "@", when used as "key1", will cause
  21.  *    lucifer to use a preset default key for "key1".  This is used
  22.  *    for verification and testing.  Failing to specify "ivec", if
  23.  *    required, will result in "key1" being used for both keys.  It
  24.  *    is an error to omit "key1".  There is no provision for specifying
  25.  *    arbitrary, absolute, bit-valued keys.
  26.  *
  27.  *    As painful as they are to use, long keys are MUCH safer.
  28.  *
  29.  *                    ~~ Graven Cyphers, 8404.16
  30.  *                       University of Toronto
  31.  */
  32.  
  33. #include "a:stdio.h"
  34. #define toascii(a)    ((a)&0177)
  35. #define EN    0
  36. #define DE    1
  37. #define CKS    2
  38. #define MODS    3
  39. typedef char    BYTE;    /* BYTE = (VAX) ? int : char;    */
  40. typedef int    void;    /* void = ("void") ? N/A : int; */
  41.  
  42. /* cryptographic declarations    */
  43. void copy16(), xor16(), getkey(), loadkey(), lucifer();
  44. BYTE Block[16], Link[16], Temp[16], IV[16];
  45. BYTE DFLTKY[16] = { 1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,16 };
  46.     /* DO NOT ALTER! => 0x0123456789abcdeffedcba9876543210 <=    */
  47.  
  48. /* I/O declarations    */
  49. void ruderr(), put16(), vraiput(), initio();
  50. int IOedf, End, Once;
  51. BYTE Last[16];
  52.  
  53. int Ecb(), Cbc(), Cks();
  54. struct modes {
  55.     char *name;
  56.     int (*func)();
  57.     };
  58. struct modes ModsOp[MODS] = {    /* CAPS for CP/M - sorry!    */
  59.     { "ECB", Ecb },
  60.     { "CBC", Cbc },
  61.     { "CKS", Cks }  };
  62.  
  63. main(argc, argv)
  64. int argc;
  65. char **argv;
  66.     {
  67.     int (*xeqtr)();
  68.     int step, ende, edio, ok, i;
  69.     BYTE kv[16];
  70.  
  71.     argv++; argc--;
  72.     if(argc > 3 || argc < 2) ruderr();
  73.  
  74.     for(step=0; argc > 0; step++) {
  75.         switch(step) {
  76.         case 0: /* set en/de and/or default mode    */
  77.             if(*argv[0] == '+' || *argv[0] == '-') {
  78.                 ende = (*argv[0] == '+') ? EN : DE;
  79.                 *argv[0]++ = NULL;
  80.                 if(*argv[0] == NULL) {
  81.                     xeqtr = Ecb;    /* default mode */
  82.                     edio = ende;
  83.                     argv++; argc--;
  84.                     break;
  85.                     }
  86.                 }
  87.             else ende = EN;
  88.  
  89.             for(i=ok=0; i < MODS && !ok; i++) {
  90.                 if(strcmp(argv[0], ModsOp[i].name) == 0) {
  91.                     xeqtr = ModsOp[i].func;
  92.                     ok = 1;
  93.                     }
  94.                 }
  95.             if(!ok) {
  96.                 fprintf(stderr, "Lucifer: unknown mode >%s<.\n", argv[0]);
  97.                 ruderr();
  98.                 }
  99.             while(*argv[0]) *argv[0]++ = NULL;
  100.             argv++; argc--;
  101.  
  102.             /* set appropriate IO modes    */
  103.             if(xeqtr == Cks) edio = CKS;
  104.             else edio = ende;
  105.  
  106.         /* falling through....    */
  107.         case 1: /* get the key and IV, if needed and present    */
  108.             if(strcmp(argv[0], "@") == 0) copy16(DFLTKY, kv);
  109.             else getkey(argv[0], kv);
  110.             argv++; argc--;
  111.  
  112.             /* if nothing left, but an IV needed, use the key    */
  113.             if(argc == 0) {
  114.                 if(xeqtr != Ecb) copy16(kv, IV);
  115.                 break;
  116.                 }
  117.             else if(xeqtr == Ecb) {
  118.                 fprintf(stderr, "Lucifer: ivec ignored.\n");
  119.                 while(*argv[0]) *argv[0]++ = NULL;
  120.                 argv++; argc--;
  121.                 break;
  122.                 }
  123.  
  124.             else getkey(argv[0], IV);
  125.             argv++; argc--;
  126.             break;
  127.  
  128.         default:
  129.             fprintf(stderr, "Lucifer: Programming error!\n");
  130.             exit(1);
  131.             break;
  132.             }    /* switch    */
  133.         }    /* argument parsing    */
  134.  
  135.     initio(edio);
  136.     loadkey(kv, ende);
  137.     (*xeqtr)(ende);     /* ta-da!  Take it away xeqtr!    */
  138.     exit(0);
  139.     }    /* end of main    */
  140.  
  141. void ruderr() {
  142.     fprintf(stderr, "Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>\n");
  143.     exit(1);
  144.     }
  145.  
  146. Cbc(e_d)    /* Cipher Block Chaining        */
  147. int e_d;    /* Ciphertext errors are self-healing.    */
  148.     {
  149.     copy16(IV, Link);
  150.     while(get16(Block) != EOF) {
  151.         if(e_d == DE) copy16(Block, Temp);
  152.         else xor16(Block, Link);
  153.         lucifer(Block);
  154.         if(e_d == DE) {
  155.             xor16(Block, Link);
  156.             copy16(Temp, Link);
  157.             }
  158.         else copy16(Block, Link);
  159.         put16(Block);
  160.         }
  161.     return;
  162.     }
  163.  
  164. Cks(dummy)    /* CBC authentication checksum generator    */
  165. int dummy;    /* The banks use this for verifications.    */
  166.     {
  167.     int i, j, k;
  168.     long count = 0;
  169.     copy16(IV, Link);
  170.     while(get16(Block) != EOF) {
  171.         xor16(Block, Link);
  172.         lucifer(Block);
  173.         copy16(Block, Link);
  174.         count += 16L;
  175.         }
  176.     fprintf(stdout, ": %0ld bytes\t: ", count);
  177.     for(i=j=0; i < 4; i++) {
  178.         for(k=0; k < 4; k++, j++) fprintf(stdout, "%02x", Link[j]&0377);
  179.         putc(' ', stdout);
  180.         }
  181.     fprintf(stdout, ":\n");
  182.     return;
  183.     }
  184.  
  185. Ecb(dummy)    /* Electronic Code Book : simple substitution    */
  186. int dummy;    /* Yawn.  For static data and random access.    */
  187.     {
  188.     while(get16(Block) != EOF) {
  189.         lucifer(Block);
  190.         put16(Block);
  191.         }
  192.     return;
  193.     }
  194.  
  195. void copy16(from, to)
  196. register BYTE *from, *to;
  197.     {
  198.     register BYTE *ep;
  199.     ep = &to[16];
  200.     while(to < ep) *to++ = *from++;
  201.     return;
  202.     }
  203.  
  204. void xor16(to, with)
  205. register BYTE *to, *with;
  206.     {
  207.     register BYTE *ep;
  208.     ep = &to[16];
  209.     while(to < ep) *to++ ^= *with++;
  210.     return;
  211.     }
  212.  
  213. void put16(block)
  214. register BYTE *block;
  215.     {
  216.     if(IOedf == DE) copy16(block, Last);
  217.     else vraiput(block, &block[16]);
  218.     return;
  219.     }
  220.  
  221. get16(input)
  222. register char *input;
  223.     {
  224.     register int i, j;
  225.     if(End == 1) return(EOF);    /* no more input    */
  226.  
  227.     for(i=0; i < 16 && ((j = getc(stdin)) != EOF); i++) *input++ = j;
  228.  
  229.     if(IOedf == DE) {    /* DECRYPTION    */
  230.         if(i == 16 && (Once > 0)) vraiput(Last, &Last[16]);
  231.         else if(j == EOF) {
  232.             End = 1;
  233.             if(Once > 0) {
  234.                 if(i != 0) i = 0;    /* no NULLs    */
  235.                 else {
  236.                     i = Last[15]&037;
  237.                     if(i > 16) i = 0;    /* huh? */
  238.                     }
  239.                 vraiput(Last, &Last[16-i]);
  240.                 }
  241.             return(EOF);
  242.             }
  243.         }
  244.     else if(j == EOF) {    /* ENCRYPTION    */
  245.         End = 1;
  246.         if(i == 0 && (IOedf == EN || (Once > 0))) {
  247.             if(IOedf == EN && (Once > 0)) putc('0', stdout);
  248.             return(EOF);
  249.             }
  250.         for(j=i; j < 15; j++) *input++ = NULL;
  251.         *input = 16-i;
  252.         }
  253.     Once = 1;
  254.     return(0);
  255.     }
  256.  
  257. void vraiput(cp, ep)
  258. register char *cp, *ep;
  259.     {
  260.     while(cp < ep) putc(*cp++, stdout);
  261.     return;
  262.     }
  263.  
  264. void initio(edf)
  265. int edf;
  266.     {
  267.     IOedf = edf;
  268.     End = Once = 0;
  269.     return;
  270.     }
  271.  
  272. /* LUCIFER is a cryptographic algorithm developed by IBM in the early
  273.  *    seventies.  It was a predecessor of the DES, and is much simpler
  274.  *    than that algorithm.  In particular, it has only two substitution
  275.  *    boxes and just one permutation box.  The permutation box is only
  276.  *    eight bits wide.  It does, however, use a 128 bit key and operates
  277.  *    on sixteen byte data blocks...
  278.  *
  279.  *    This implementation of LUCIFER was crafted by Graven Cyphers at the
  280.  *    University of Toronto, Canada, with programming assistance from
  281.  *    Richard Outerbridge.  It is based on the FORTRAN routines which
  282.  *    concluded Arthur Sorkin's article "LUCIFER: A Cryptographic Algorithm",
  283.  *    CRYPTOLOGIA, Volume 8, Number 1, January 1984, pp22-42.  The interested
  284.  *    reader should refer to that article rather than this program for more
  285.  *    details on LUCIFER.
  286.  *
  287.  *    These routines bear little resemblance to the actual LUCIFER algorithm,
  288.  *    which has been severely twisted in the interests of speed.  They do
  289.  *    perform the same transformations, and are believed to be UNIX portable.
  290.  *    The package was developed for use on UNIX-like systems lacking crypto
  291.  *    facilities.  They are not very fast, but the cipher is very strong.
  292.  *    The routines in this file are suitable for use as a subroutine library
  293.  *    after the fashion of crypt(3).    When linked together with applications
  294.  *    routines they can also provide a high-level cryptographic system.
  295.  */
  296.  
  297. static BYTE Dps[64] = {     /* Diffusion Pattern schedule    */
  298.     4,16,32,2,1,8,64,128,    128,4,16,32,2,1,8,64,
  299.     64,128,4,16,32,2,1,8,    8,64,128,4,16,32,2,1,
  300.     1,8,64,128,4,16,32,2,    2,1,8,64,128,4,16,32,
  301.     32,2,1,8,64,128,4,16,    16,32,2,1,8,64,128,4    };
  302.  
  303. /* Precomputed S&P Boxes, Two Varieties */
  304. static char TCB0[256] = {    /* NB: char to save space.    */
  305.      87, 21,117, 54, 23, 55, 20, 84,116,118, 22, 53, 85,119, 52, 86,
  306.     223,157,253,190,159,191,156,220,252,254,158,189,221,255,188,222,
  307.     207,141,237,174,143,175,140,204,236,238,142,173,205,239,172,206,
  308.     211,145,241,178,147,179,144,208,240,242,146,177,209,243,176,210,
  309.     215,149,245,182,151,183,148,212,244,246,150,181,213,247,180,214,
  310.      95, 29,125, 62, 31, 63, 28, 92,124,126, 30, 61, 93,127, 60, 94,
  311.     219,153,249,186,155,187,152,216,248,250,154,185,217,251,184,218,
  312.      67,  1, 97, 34,  3, 35,  0, 64, 96, 98,  2, 33, 65, 99, 32, 66,
  313.     195,129,225,162,131,163,128,192,224,226,130,161,193,227,160,194,
  314.     199,133,229,166,135,167,132,196,228,230,134,165,197,231,164,198,
  315.     203,137,233,170,139,171,136,200,232,234,138,169,201,235,168,202,
  316.      75,  9,105, 42, 11, 43,  8, 72,104,106, 10, 41, 73,107, 40, 74,
  317.      91, 25,121, 58, 27, 59, 24, 88,120,122, 26, 57, 89,123, 56, 90,
  318.      71,  5,101, 38,  7, 39,  4, 68,100,102,  6, 37, 69,103, 36, 70,
  319.      79, 13,109, 46, 15, 47, 12, 76,108,110, 14, 45, 77,111, 44, 78,
  320.      83, 17,113, 50, 19, 51, 16, 80,112,114, 18, 49, 81,115, 48, 82 };
  321.  
  322. static char TCB1[256] = {
  323.      87,223,207,211,215, 95,219, 67,195,199,203, 75, 91, 71, 79, 83,
  324.      21,157,141,145,149, 29,153,  1,129,133,137,  9, 25,  5, 13, 17,
  325.     117,253,237,241,245,125,249, 97,225,229,233,105,121,101,109,113,
  326.      54,190,174,178,182, 62,186, 34,162,166,170, 42, 58, 38, 46, 50,
  327.      23,159,143,147,151, 31,155,  3,131,135,139, 11, 27,  7, 15, 19,
  328.      55,191,175,179,183, 63,187, 35,163,167,171, 43, 59, 39, 47, 51,
  329.      20,156,140,144,148, 28,152,  0,128,132,136,  8, 24,  4, 12, 16,
  330.      84,220,204,208,212, 92,216, 64,192,196,200, 72, 88, 68, 76, 80,
  331.     116,252,236,240,244,124,248, 96,224,228,232,104,120,100,108,112,
  332.     118,254,238,242,246,126,250, 98,226,230,234,106,122,102,110,114,
  333.      22,158,142,146,150, 30,154,  2,130,134,138, 10, 26,  6, 14, 18,
  334.      53,189,173,177,181, 61,185, 33,161,165,169, 41, 57, 37, 45, 49,
  335.      85,221,205,209,213, 93,217, 65,193,197,201, 73, 89, 69, 77, 81,
  336.     119,255,239,243,247,127,251, 99,227,231,235,107,123,103,111,115,
  337.      52,188,172,176,180, 60,184, 32,160,164,168, 40, 56, 36, 44, 48,
  338.      86,222,206,210,214, 94,218, 66,194,198,202, 74, 90, 70, 78, 82 };
  339.  
  340. statiπ BYTE Key[16]¼ Pkey[128];
  341. static int P[8] = { 3,5,0,4,2,1,7,6 };
  342. static int Smask[16] = { 128,64,32,16,8,4,2,1 };
  343.  
  344. void lucifer(bytes)
  345. BYTE *bytes;    /* points to a 16-byte array    */
  346.     {
  347.     register BYTE *cp, *sp, *dp;
  348.     register int *sbs, tcb, val, j, i;
  349.     BYTE *h0, *h1, *kc, *ks;
  350.  
  351.     h0 = &bytes[0];     /* the "lower" half     */
  352.     h1 = &bytes[8];     /* the "upper" half     */
  353.     kc = Pkey;
  354.     ks = Key;
  355.  
  356.     for(i=0; i<16; i++) {
  357.         tcb = *ks++;
  358.         sbs = Smask;
  359.         dp = Dps;
  360.  
  361.         for(j=0; j<8; j++) {
  362.             /* nibbles are selected by the bits of ks    */
  363.             if(tcb&*sbs++) val = TCB1[h1[j]&0377];
  364.             else val = TCB0[h1[j]&0377];
  365.             val ^= *kc++;
  366.  
  367.             /* fiddle bits in the "lower" half      */
  368.             for(cp=h0, sp = &h0[8]; cp<sp; cp++)
  369.                 *cp ^= (val&*dp++);
  370.             }
  371.  
  372.         /* swap (virtual) halves    */
  373.         cp = h0;
  374.         h0 = h1;
  375.         h1 = cp;
  376.         }
  377.  
  378.     /* REALLY swap halves    */
  379.     dp = &bytes[0];
  380.     cp = &bytes[8];
  381.     for(sp=cp; dp<sp; dp++, cp++) {
  382.         val = *dp;
  383.         *dp = *cp;
  384.         *cp = val;
  385.         }
  386.     return;
  387.     }
  388.  
  389. void loadkey(keystr, edf)    /* sets master key    */
  390. BYTE *keystr;
  391. register int edf;
  392.     {
  393.     register BYTE *ep, *cp, *pp;
  394.     register int kc, i, j;
  395.     BYTE kk[16], pk[16];
  396.     cp = kk;
  397.     pp = pk;
  398.     ep = &kk[16];
  399.     while(cp < ep) {
  400.         *cp++ = *keystr;
  401.         for(*pp=i=0; i<8; i++)
  402.             if(*keystr&Smask[i]) *pp |= Smask[P[i]];
  403.         keystr++;
  404.         pp++;
  405.         }
  406.     cp = Key;
  407.     pp = Pkey;
  408.     kc = (edf == DE) ? 8 : 0;
  409.     for(i=0; i<16; i++) {
  410.         if(edf == DE) kc = (++kc)&017;
  411.         *cp++ = kk[kc];
  412.         for(j=0; j<8; j++) {
  413.             *pp++ = pk[kc];
  414.             if(j<7 || (edf == DE)) kc = (++kc)&017;
  415.             }
  416.         }
  417.     return;
  418.     }
  419.  
  420. /* getkey: using up to 16 bytes of aptr, makeup a 16 byte key in savp.
  421.     aptr must be NULL terminated, savp 16 bytes long.  The key
  422.     returned in savp is aptr encrypted with itself ONCE.    */
  423. void getkey(aptr, savp)
  424. register char *aptr;
  425. register BYTE *savp;
  426.     {
  427.     register BYTE *store, *cp;
  428.     register int i;
  429.     store = savp;
  430.  
  431.     /* copy aptr into savp; NULL aptr    */
  432.     for(i=0; i<16 && (*aptr != NULL); i++) {
  433.         *savp++ = toascii(*aptr);
  434.         *aptr++ = NULL;
  435.         }
  436.     while(*aptr) *aptr++ = NULL;
  437.     if(i == 0) savp++;    /* aptr could have been NULL    */
  438.  
  439.     /* expand savp out to 16 bytes of "something" and encrypt it    */
  440.     for(cp=store, savp--; i<16;) store[i++] = (*cp++ + *savp++)&0377;
  441.     loadkey(store);
  442.     lucifer(store);
  443.     return;
  444.     }
  445.  
  446. /*    lucifer cks @ < /dev/null
  447.  *    : 16 bytes    : 32186510 6acf6094 87953eba 196f5a75 :
  448.  *            (rwo/8406.23.16:37/V3.2)            */
  449. /**************************** lucifer ***********************************/
  450.  
  451.